import _thread
import re

from flask import g, Blueprint, request, redirect, session
from flask_login import login_user, login_required
from sqlalchemy import and_, or_

from common import Result
from forms import RegisterRequestsForm, LoginForm, UpdatePasswdForm
from models import User
from exts import db, get_time, to_json_all, send_mail, get_verification_code

bp = Blueprint("api_user", __name__, url_prefix="/api/user")


# todo /update_passwd
@bp.route("/update_passwd", methods=['POST'])
@login_required
def update_passwd():
    upf = UpdatePasswdForm(request.form)
    if upf.validate():
        g.user.password = upf.password.data
        db.session.commit()

        return Result.success(
            msg="修改成功"
        )
    else:
        return Result.error(
            msg=str(upf.errors)
        )


# todo /login_in
@bp.route("/login_in", methods=['POST'])
def login_in():
    data = eval(request.form.get("data"))
    lf = LoginForm(**data)

    if lf.validate():
        user = db.session.query(User).filter(and_(User.phone == lf.phone.data, User.is_delete == 0)).first()
        if user is not None:
            if user.password == lf.password.data:
                login_user(user)
                return Result.success()
            else:
                return Result.error(msg="密码错误")
        else:
            return Result.error(msg="没有此用户")
    else:
        return Result.error(msg="账号或密码错误")


# todo /login_in_email
@bp.route("/login_in_email", methods=['POST'])
def login_in_email():
    email = request.form.get("email")
    verification_code = request.form.get("verification_code")

    if verification_code == session.get("verification_code"):
        user = db.session.query(User).filter(and_(
            User.email == email,
            User.is_delete == 0
        )).first()
        if user is not None:
            login_user(user)
            return Result.success()
        else:
            return Result.error(msg="没有此用户")
    else:
        return Result.error(msg="验证码错误")


# todo /login_in_phone
@bp.route("/login_in_phone", methods=['POST'])
def login_in_phone():
    phone = request.form.get("phone")
    verification_code = request.form.get("verification_code")

    if verification_code == session.get("verification_code"):
        user = db.session.query(User).filter(and_(
            User.phone == phone,
            User.is_delete == 0
        )).first()
        if user is not None:
            login_user(user)
            return Result.success()
        else:
            return Result.error(msg="没有此用户")
    else:
        return Result.error(msg="验证码错误")


# todo /send_verification_code
@bp.route("/send_verification_code", methods=['POST'])
def send_verification_code():
    email = request.form.get("email")
    if re.search(r"^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$", email):

        if db.session.query(User).filter(and_(
            User.email == email,
            User.is_delete == 0
        )).first() is None:
            return Result.error(
                msg='没有此用户'
            )

        verification_code = get_verification_code()
        session["verification_code"] = verification_code

        _thread.start_new_thread(send_mail, ("验证码", [email], f"{verification_code}为您的登录验证码，请于5分钟内填写，如非本人操作，请忽略本邮件。", g.ctx))

        return Result.success(
            msg="验证码已发送"
        )
    else:
        return Result.error(
            msg="请输入正确的邮箱"
        )


# todo /send_phone_verification_code
@bp.route("/send_phone_verification_code", methods=['POST'])
def send_phone_verification_code():
    phone = request.form.get("phone")
    if re.search(r"^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\d{8}$", phone):

        if db.session.query(User).filter(and_(
            User.phone == phone,
            User.is_delete == 0
        )).first() is None:
            return Result.error(
                msg='没有此用户'
            )

        verification_code = get_verification_code()
        session["verification_code"] = verification_code

        send_message([phone], [verification_code, "5"])

        return Result.success(
            msg="验证码已发送"
        )
    else:
        return Result.error(
            msg="请输入正确的电话"
        )
